package com.gscitysfy.cus.drain.modules.duty.service.impl;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gscitysfy.cloudfrmwk.portal.feign.DictionaryService;
import com.gscitysfy.cloudfrmwk.security.definition.core.HerodotusUserDetails;
import com.gscitysfy.cloudfrmwk.security.utils.SecurityUtils;

import com.gscitysfy.cus.drain.constants.DicConstant;
import com.gscitysfy.cus.drain.enums.PlatformEnum;
import com.gscitysfy.cus.drain.modules.duty.mapper.MoperDutyScheduleMapper;
import com.gscitysfy.cus.drain.modules.duty.service.IMoperDutyScheduleService;
import com.gscitysfy.cus.drain.modules.duty.vo.MoperDutyMnRotaVo;
import com.gscitysfy.cus.drain.utils.HttpResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author 刘少华
 * @version 1.0
 * @description: 值班排班查询接口实现类
 * @date 2022/3/28 12:16
 */
@Service
@Slf4j
public class MoperDutyScheduleServiceImpl extends ServiceImpl<MoperDutyScheduleMapper, MoperDutyMnRotaVo> implements IMoperDutyScheduleService {

    @Autowired
    private MoperDutyScheduleMapper dutyScheduleMapper;

    @Autowired
    private DictionaryService dictionaryService;

    /**
     * 按日期分组查询排班
     *
     * @param startTime
     * @param endTime
     * @param personType
     * @param coamClass
     * @param isOwn
     * @return 按日期分组的值班数据HashMap
     */
    @Override
    public Map<String, List<MoperDutyMnRotaVo>> listDutyScheduleGroupByDate(String startTime, String endTime, String personType, String coamClass, String isOwn,String personId) {
        Map<String, List<MoperDutyMnRotaVo>> mapDate = new HashMap<>(64);

        //判断是否当前用户排班：1-是，0-否
        if (PlatformEnum.DUTY_IS_OWN_FLAG.getCode().equalsIgnoreCase(isOwn)) {
            HerodotusUserDetails principal = SecurityUtils.getPrincipal();
            if (principal != null) {
                personId = principal.getUserId();
            }
        }
        List<MoperDutyMnRotaVo> listRota = dutyScheduleMapper.listDutySchedule(startTime, endTime, personType, coamClass, personId);
        if (!listRota.isEmpty()) {
            //重新打包同一日期的值班数据
            for (MoperDutyMnRotaVo dutyRota : listRota) {
                if (mapDate.keySet().contains(dutyRota.getCoamGroupDate())) {
                    mapDate.get(dutyRota.getCoamGroupDate()).add(dutyRota);
                } else {
                    List<MoperDutyMnRotaVo> listDate = new ArrayList<>();
                    listDate.add(dutyRota);
                    mapDate.put(dutyRota.getCoamGroupDate(), listDate);
                }

            }
        }
        return mapDate;
    }

    /**
     * 按条件查询值班日历
     * @param dutyTime
     * @param personType
     * @param coamClass
     * @param personId
     * @return
     */
    @Override
    public List<MoperDutyMnRotaVo> getDutySchedule (String dutyTime, String personType, String coamClass, String personId,String isAll){
        //人员ID传参为空默认取当前登录账户
        if(StringUtils.isEmpty(personId)){
            HerodotusUserDetails principal = SecurityUtils.getPrincipal();
            if (principal != null) {
                personId = principal.getUserId();
            }
        }
        if (StringUtils.isNotEmpty(isAll)){
            personId = null;
        }
        return dutyScheduleMapper.getDutySchedule(dutyTime, personType, coamClass, personId);
    }

    /**
     * 分页查询排班日历列表
     *
     * @param startTime
     * @param endTime
     * @param personName
     * @param coamClass
     * @return
     */
    @Override
    public IPage<MoperDutyMnRotaVo> listDutySchedulePage(Page<MoperDutyMnRotaVo> page, String startTime, String endTime, String personName, String coamClass) {
        return dutyScheduleMapper.listDutySchedulePage(page, startTime, endTime, coamClass, personName);
    }

    /**
     * 按条件导出值班日历
     *
     * @param response
     * @param startTime
     * @param endTime
     * @param personType
     * @param coamClass
     * @param isOwn
     */
    @Override
    public void exportDutySchedule(HttpServletResponse response, String startTime, String endTime, String personType, String coamClass, String isOwn) {
        //获取传入日期所在年月
        String headerMonth = StringUtils.substring(startTime, 0, 4) + "年" + StringUtils.substring(startTime, 5, 7) + "月";
        String personId = "";
        //判断是否当前用户排班：1-是，0-否
        if (PlatformEnum.DUTY_IS_OWN_FLAG.getCode().equalsIgnoreCase(isOwn)) {
            HerodotusUserDetails principal = SecurityUtils.getPrincipal();
            if (principal != null) {
                personId = principal.getUserId();
            }
        }
        exportSchedule(response, dutyScheduleMapper.listDutySchedule(startTime, endTime, personType, coamClass, personId), headerMonth);
    }

    /**
     * 导出排班表格
     *
     * @param response
     * @param listRota
     * @param headerMonth
     */
    private void exportSchedule(HttpServletResponse response, List<MoperDutyMnRotaVo> listRota, String headerMonth) {
        try (ExcelWriter writer = ExcelUtil.getWriter(true); OutputStream out = response.getOutputStream()) {
            String filename = headerMonth + "值班记录列表.xlsx";
            HttpResponseUtil.setResponseHeaders(response, filename);
            writer.setOnlyAlias(true);
            //设置表头
            writer.addHeaderAlias("coamGroupDate", "值班日期");
            writer.addHeaderAlias("coamClassName", "班次");
            writer.addHeaderAlias("classStartTime", "开始时间");
            writer.addHeaderAlias("classEndTime", "结束时间");
            writer.addHeaderAlias("coamPersonUsername", "值班人员");
            writer.addHeaderAlias("coamPersonType", "人员类别");

            //判断为空则单独写入头数据
            if (listRota.isEmpty()) {
                writer.writeHeadRow(new ArrayList<String>() {{
                    add("值班日期");
                    add("班次");
                    add("开始时间");
                    add("结束时间");
                    add("值班人员");
                    add("人员类别");
                }});
            } else {
                //值班人员类别枚举转换
                Map<String, String> dutyTypeMap = dictionaryService.getDictionaryMap(DicConstant.DUTY_TYPE).getData();
                listRota.forEach(
                    item -> item.setCoamPersonType(dutyTypeMap.get(item.getCoamPersonType()))
                );
            }
            writer.write(listRota, true);
            writer.flush(out);
        } catch (IOException e) {
            log.error("export duty calendar list error!");
        }
    }
}
